#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright © 2018-2021 Arm Limited.
# SPDX-License-Identifier: Apache-2.0
#

import os
import common

Import('env')

common.setup_common_env(env)
common.setup_toolchain(env, env['platform'])

# Note we *prepend* so these take priority over CPATH command-line-arguments to avoid depending on the install target
# where the install target is also provided via CPATH.
env.PrependUnique(CPPPATH=[os.path.join(env['command_stream_dir'], 'include'),
                           os.path.join(env['utils_dir'], 'include'),
                           env['kernel_module_dir']])
# Set the appropriate CPP define for the target.
env.Append(CPPDEFINES=['TARGET_' + env['target'].upper()])

srcs = [os.path.join('src', 'Inference.cpp'),
        os.path.join('src', 'Buffer.cpp'),
        os.path.join('src', 'Network.cpp'),
        os.path.join('src', 'ProfilingInternal.cpp'),
        os.path.join('src', 'DumpProfiling.cpp'),
        os.path.join('src', 'NetworkImpl.cpp')]

if env['target'] == 'kmod':
    srcs += [os.path.join('src', 'KmodNetwork.cpp'),
             os.path.join('src', 'KmodProfiling.cpp')]
    env.AppendUnique(CPPDEFINES=['DEVICE_NODE={}'.format(env['device_node'])])
    env.AppendUnique(CPPDEFINES=['FIRMWARE_PROFILING_NODE={}'.format(env['firmware_profiling_node'])])
else:
    srcs += [os.path.join('src', 'NullKmodProfiling.cpp')]

if env['target'] == 'model':
    # Compile internal-only model files, which are stored outside of this component's folder.
    # Use a scons 'repository' so that the build artifacts (.o files) are still placed in the expected build directory.
    # Extend CPPPATH to allow the model cpp files to include headers from the regular src folder, and to allow
    # regular src files to include headers from the model-only folder.
    # Note we *prepend* so these take priority over CPATH command-line-arguments to avoid depending on
    # the install target where the install target is also provided via CPATH.
    env.PrependUnique(CPPPATH=['.', 'src'])
    env.Repository(os.path.join(env['driver_library_dir'], '..', '..', 'internal', 'driver'))
    srcs += [os.path.join('src', 'ModelNetwork.cpp')]

libs = []

# Add dependency on libXmlToBinary and libmxml if we need to be able to dump command streams.
# This is controlled by a build option as these extra dependencies will not be wanted in a production environment.
if env['allow_command_stream_dump']:
    env.AppendUnique(CPPDEFINES=['ETHOSN_ALLOW_COMMAND_STREAM_DUMP=1'])
    env.PrependUnique(CPPPATH=[env['lib_xml_to_binary_dir']])
    lib_xml_to_binary = File(os.path.join(common.get_lib_xml_to_binary_build_dir(env), 'libXmlToBinary.a'))
    libs.extend([lib_xml_to_binary, 'mxml'])

# Build driver_library static and shared lib
ethosn_driver_lib = env.StaticLibrary('libEthosNDriver', srcs)
env.Alias('install', env.Install(env['install_lib_dir'], ethosn_driver_lib))

# Note we must explicitly set the SONAME to override the default which uses a path relative to the current directory.
# This means that when the runtime linker looks for the .so, it uses the filename only and not the relative path.
# We need to clone the env to make sure we don't pollute these LINKFLAGS into subsequent builders.
# Note: can't just pass this special LINKFLAGS to SharedLibrary as that would override the existing one we have,
#       which may have --coverage and other flags.
soEnv = env.Clone()
soEnv.Append(LINKFLAGS='-Wl,-soname=libEthosNDriver.so')
# On non-Unix platforms, the static and shared lib filenames may collide, so use a different name
shared_lib_name = 'libEthosNDriver' if env['PLATFORM'] == 'posix' else 'libEthosNDriverShared'
# On non-Unix platforms, the static and shared libs may need to have different compile options, so the obj names
# need to be unique
obj_prefix = None if env['PLATFORM'] == 'posix' else 'Shared_'

libs.extend(env.get('driver_library_extra_libs', []))  # Allow extra libs to be specified by scons_extra files
ethosn_driver_shared = soEnv.SharedLibrary(shared_lib_name, srcs, LIBS=libs, SHOBJPREFIX=obj_prefix)

env.Alias('install', env.Install(env['install_lib_dir'], ethosn_driver_shared))
env.Alias('install', env.Install(os.path.join(env['install_include_dir'], 'ethosn_driver_library'),
                                 Glob(os.path.join('include', 'ethosn_driver_library', '*'))))

# Build unit tests if requested.
if env['tests']:
    SConscript(dirs='tests', duplicate=False, exports=['env', 'ethosn_driver_shared'])
